/*
 * INSANE - Interactive Structural Analysis Environment
 *
 * Copyright (C) 2003-2005
 * Universidade Federal de Minas Gerais
 * Escola de Engenharia
 * Departamento de Engenharia de Estruturas
 * 
 * Author's email :    insane@dees.ufmg.br
 * Author's website :  http://www.dees.ufmg.br/insane
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package br.ufmg.dees.insane.model.femModel.element;

import java.util.ArrayList;

import br.ufmg.dees.insane.materialMedia.degeneration.Degeneration;
import br.ufmg.dees.insane.materialMedia.degeneration.PrescribedDegeneration;
import br.ufmg.dees.insane.materialMedia.degeneration.Representation;
import br.ufmg.dees.insane.materialMedia.degeneration.Thickness;
import br.ufmg.dees.insane.materialMedia.materialPoint.MaterialPoint;
import br.ufmg.dees.insane.util.IMatrix;
import br.ufmg.dees.insane.util.INaturalCoords;
import br.ufmg.dees.insane.util.IPoint3d;
import br.ufmg.dees.insane.util.IVector;
import br.ufmg.dees.insane.util.extrapolation.TriangularLagrangeanExtrapolation2D;
import br.ufmg.dees.insane.util.numericalIntegration.AreaGaussPoint;
import br.ufmg.dees.insane.util.numericalIntegration.IntegrationPoint;

/**
 *A class representing a triangular parametric element.<p>
 *
 *@author Lucas, Marcelo & Pitangueira, Roque
 *@version 1.0
 *@since June 2004
 */

public class Triangular extends ParametricElement
{
    /**
     * Comment for <code>serialVersionUID</code>
     */
    private static final long serialVersionUID = 1L;

    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.model.femModel.element.Element#addDegeneration(java.util.ArrayList)
     */
    public void addDegeneration(Degeneration dg){
	if (dg instanceof PrescribedDegeneration) {
	    try {
		this.degenerations.add((PrescribedDegeneration)(((PrescribedDegeneration)dg).clone()));
	    }
	    catch (CloneNotSupportedException e) {
		e.printStackTrace();
	    }
	}
	else {
	    Degeneration dgn = new Thickness();
	    dgn.setOriginalLabel(dg.getOriginalLabel());

	    for(int i = 0; i<dg.getMaterialPoints().size(); i++){
		try {
		    ((Degeneration)dgn).add((MaterialPoint)(dg.getMaterialPoint(i)).clone());
		}
		catch (CloneNotSupportedException e) {
		    e.printStackTrace();
		}
	    }
	    this.degenerations.add(dgn);
	}
    }

    /* (non-Javadoc)
     * @see br.ufmg.dees.insane.model.femModel.element.Element#createDegenerations()
     */
    public void initDegenerations()
    {
	int k = 1;
	IntegrationPoint ip = new AreaGaussPoint();
	for(int i = 0; i < (this.integrationOrder.getXiIntegOrder()); i++)
	{
	    Representation representation = new Representation();
	    INaturalCoords nc = new INaturalCoords();
	    nc.setCsi1(ip.getCoord(this.integrationOrder.getXiIntegOrder()-1,(3*i)));
	    nc.setCsi2(ip.getCoord(this.integrationOrder.getXiIntegOrder()-1,(3*i+1)));
	    representation.setNaturalcoords(nc);
	    representation.setWeight(ip.getWeight(this.integrationOrder.getXiIntegOrder()-1,i));
	    representation.setAnalysisModel(this.getAnalysisModel());
	    representation.setCm(this.getConstitutiveModel());
	    ((Degeneration)this.getDegenerations().get(k-1)).setRepresentation(representation);
	    ((Degeneration)this.getDegenerations().get(k-1)).setLabel("IP-"+k);
	    k++;
	}
    }

    /** Return the element integrationCoefficient
     *@return The thickness * 1/2 of this triangular parametric element.
     */
    public double getElmCoefficient()
    {
	return 0.5;
    }

    @Override
    public IVector extrapolatesToNodes(ArrayList natCoords, ArrayList value) {
	TriangularLagrangeanExtrapolation2D extra = new TriangularLagrangeanExtrapolation2D(natCoords,value);
	IMatrix nodeNatCoords = this.Shape.getNaturalNodalCoords();
	IVector values = new IVector(nodeNatCoords.getNumCol());
	for (int i = 0; i < nodeNatCoords.getNumCol(); i++) {
	    IPoint3d p = new IPoint3d(nodeNatCoords.getElement(0,i),nodeNatCoords.getElement(1,i));
	    values.setElement(i,extra.extrapolateTo(p));
	}
	return values;
    }

}
